from flask import views, render_template, request, url_for, \
    redirect, Blueprint, make_response
import json
import urllib.request
from datetime import datetime
from sqlalchemy.exc import SQLAlchemyError
from mysql_config import db
from models import Location
from models import UserOrder
from models import Car
from models import ItemState
from result import Result
from result_code import Code
from utils.planning import planning, loc_str

gaode = Blueprint('gaode', __name__)


@gaode.route('/test', methods=['POST'])
def gaodetest():
    if request.content_type.startswith('application/json'):
        res = request.get_data()
        print(res)
        try:
            order_id = request.json.get("order_id")
            print(order_id)
            return {'code': 1}
        except Exception as e:
            print(e)
            return {'code': 0}


@gaode.route('/task', methods=['GET'])
def has_task():
    userorder = UserOrder.query.filter(UserOrder.state == 1).first()
    if userorder is None:
        return {'code': 0, 'data': 0, 'msg': '暂无等待配送的订单'}
    else:
        return {'code': 0, 'data': 1, 'msg': '有待配送的订单'}


@gaode.route('/task', methods=['POST'])
def task():
    car_pt = request.json.get("car_pt")  # 小车的起点坐标
    car_id = request.json.get("car_id")
    i_temp = request.json.get("i_temp")
    i_hum = request.json.get("i_hum")
    # print(car_pt)
    # 获取首个等待配送的订单
    userorder = UserOrder.query.filter(UserOrder.state == 1).first()
    if userorder is None:
        return {'code': 0, 'data': None, 'msg': '暂无等待配送的订单'}

    res_car = Car.query.filter(Car.car_id == car_id).first()
    if res_car is None:
        return {'code': -1, 'data': None, 'msg': '该配送车不存在'}
    else:
        userorder.car_id = res_car.car_id

    userorder.state = 2
    userorder.car_id = car_id
    oid = userorder.order_id
    begin_lnglat = userorder.begin_lnglat  # 货物的起点坐标
    end_lnglat = userorder.end_lnglat  # 货物的终点坐标

    path1 = planning(car_pt, begin_lnglat)
    path2 = planning(begin_lnglat, end_lnglat)
    paths = {'path1': path1, 'path2': path2}
    if path1 is False or path2 is False:
        return {'code': -1, 'data': None, 'msg': '路径规划失败'}

    # 收到任务后添加该订单对应的Location记录
    res_loc = Location.query.filter(Location.order_id == oid).first()
    _str = loc_str(car_pt)  # 地理逆编码
    if res_loc is None:
        loc = Location(order_id=oid, point=car_pt, loc=_str)
        db.session.add(loc)
    else:
        res_loc.point = car_pt
        res_loc.loc = _str

    # 收到任务后添加该订单对应的ItemState记录
    res_state = ItemState.query.filter(ItemState.order_id == oid).first()
    if res_state is None:
        item_state = ItemState(order_id=oid, i_temp=i_temp, i_hum=i_hum)
        db.session.add(item_state)
    else:
        res_state.i_temp = i_temp
        res_state.i_hum = i_hum

    db.session.commit()
    return {'code': 1, 'data': {'paths': paths, 'oid': oid}, 'msg': '路径规划成功'}


@gaode.route('/task_back', methods=['POST'])
def task_back():
    code = request.json.get("code")
    oid = request.json.get("oid")
    state = request.json.get("state")
    if state == 2 or state == 3 or state == 4 or state == 5:
        if code == 1:
            res_order = UserOrder.query.filter(UserOrder.order_id == oid).first()
            if res_order is None:
                return {'code': -1, 'msg': '操作失败'}
            try:
                res_order.state = state
                db.session.commit()
                return {'code': 1, 'msg': '操作成功'}
            except SQLAlchemyError as e:
                print(e)
                db.session.rollback()
                return {'code': -1, 'msg': '操作失败'}
        else:
            return {'code': 1, 'msg': '操作成功'}
    else:
        return {'code': -1, 'msg': '操作失败'}


@gaode.route('/loc_update', methods=['POST'])
def loc_update():
    oid = request.json.get("oid")
    pt = request.json.get("pt")
    res_loc = Location.query.filter(Location.order_id == oid).first()
    if res_loc is None:
        loc = Location(order_id=oid, point=pt)
        db.session.add(loc)
        db.session.commit()
    else:
        res_loc.point = pt
        db.session.commit()
    return {'msg': '操作成功'}


@gaode.route('/pts', methods=['POST'])
def planning_pts():
    origin = request.json.get("origin")
    destination = request.json.get("destination")
    key = '78019793b012a9c6b8e361aa55f9282c'
    url = 'https://restapi.amap.com/v5/direction/walking?key='
    url += key + '&origin=' + origin + '&destination=' + destination + '&isindoor=0&show_fields=cost,polyline'
    response = urllib.request.urlopen(url).read()
    res_dic = json.loads(response)
    # print(res_dic)
    status = res_dic['status']
    if status != '1':
        return vars(Result(Code.GET_ERR.value, None, '路径规划失败'))

    paths = res_dic['route']['paths']
    total_distance = 0
    pts_li_temp = []
    for path in paths:
        total_distance += int(path['distance'])
        steps = path['steps']
        for step in steps:  # step : 'xxx.xxx,xxx.xxx;xxx.xxx,xxx.xxx;...'
            pts_li_temp.extend(step['polyline'].split(';'))
    pts = list(set(pts_li_temp))  # 去重
    pts.sort(key=pts_li_temp.index)
    # print(pts)
    pts_2 = []
    for pt in pts:
        temp_list = pt.split(',')
        temp_list[0] = float(temp_list[0])
        temp_list[1] = float(temp_list[1])
        pts_2.append(temp_list)  # 二维列表
    # print(pts_2)
    return vars(Result(Code.GET_OK.value, {'total_distance': total_distance, 'pts': pts_2}, '路径规划成功'))


@gaode.route('/inverse_coding', methods=['POST'])
def inverse_coding():
    code = request.json.get("code")
    key = ''
    with open(file='controller/key.txt', mode='r', encoding='utf-8') as fb:
        key = fb.readline()
    url = 'https://restapi.amap.com/v3/geocode/regeo?key='
    url += key + '&location=' + code
    response = urllib.request.urlopen(url).read()
    res_dic = json.loads(response)
    status = res_dic['status']
    if status == 0:
        return {Code.GET_ERR.value, None, "经纬度转换失败"}
    print(res_dic)
    # res_dic['regeocode']['addressComponent']['streetNumber']['number']
    regeocode = res_dic['regeocode']
    addressComponent = regeocode['addressComponent']
    province = addressComponent['province']  # 省
    city = addressComponent['city']  # 市(若是直辖市，此处为空列表)
    if city is []:
        city = None
    township = addressComponent['township']  # 镇
    district = addressComponent['district']  # 区/县
    street = addressComponent['streetNumber']['street']  # 街道
    number = addressComponent['streetNumber']['number']
    street += number
    addr_str = regeocode['formatted_address'] + number
    resp_dic = {'pro': province, 'city': city, 'township': township, 'dist': district, 'street': street}
    return vars(Result(Code.GET_OK.value, {'regeocode': resp_dic, 'addr_str': addr_str}, '经纬度转换成功'))

